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

永遠(yuǎn)也不完美的程序

不斷學(xué)習(xí),不斷實(shí)踐,不斷的重構(gòu)……

常用鏈接

統(tǒng)計(jì)

積分與排名

好友鏈接

最新評(píng)論

shader復(fù)雜與深入:Normal Map(法線貼圖)1

轉(zhuǎn)自:http://www.zwqxin.com/archives/shaderglsl/review-normal-map-bump-map.html
Normal Map法線貼圖,想必每個(gè)學(xué)習(xí)計(jì)算機(jī)圖形學(xué)的人都不陌生。今天在這里按我的理解總結(jié)一下,作為復(fù)習(xí),也作為深入學(xué)習(xí)吧。——ZwqXin.com
自從看完那本《數(shù)學(xué)在計(jì)算機(jī)圖形學(xué)上的應(yīng)用》后,一直想好好地真正實(shí)踐一次法線貼圖/凹凸貼圖呢(以前是根據(jù)橙書(shū)弄了一下罷了)。昨天偶爾看到篇涉及BumpMap的文,正好覺(jué)得是個(gè)機(jī)會(huì),便在網(wǎng)上狂找相關(guān)資料——果然,越看越覺(jué)得自己還有很多理論的地方需要弄明白呢。
說(shuō)起Normal Map(法線貼圖),就會(huì)想起B(yǎng)ump Map(凹凸貼圖)。Bump Mapping是Blin大師在1978年提出的圖形學(xué)算法,目的是以低代價(jià)給予計(jì)算機(jī)幾何體以更豐富的表面信息(高模蓋低模)。30年來(lái),這項(xiàng)技術(shù)不斷延展,尤其是計(jì)算機(jī)圖形學(xué)成熟以后,相繼出現(xiàn)了不少算法變體,90年代末的Normal Map解放了必須自行計(jì)算紋理像素法線的痛苦,新世紀(jì)以來(lái)相繼又出現(xiàn)了Parallax Mapping, Relief Mapping等技術(shù)。拋開(kāi)那些無(wú)聊的概念區(qū)分,它們的本體還是Bump Map,目的也是一致的。
1. 傳統(tǒng)的Bump Map
如果你對(duì)純凈的Bump Map有興趣,A Practical and Robust Bump-mapping Technique for Today's GPU應(yīng)該是值得一看的論文。說(shuō)Today,其實(shí)是GDC 2000的事情了,但對(duì)于傳統(tǒng)的Bump Map的理論是很豐富的,我是沒(méi)精力看完它啦……
那時(shí)候的Bump Map須要我們計(jì)算紋理圖上每個(gè)像素的法線信息,簡(jiǎn)單的還可能做到,對(duì)復(fù)雜的紋理要搞清面光背光份量簡(jiǎn)直要命,于是就用Height Map,在一張高度圖上記錄每個(gè)像素對(duì)應(yīng)的紋理位置的高度信息(這個(gè)比較容易辦到,NEHE22也是這類)。看上去就是一張地形網(wǎng)格——這樣的話,計(jì)算每個(gè)像素點(diǎn)的法線就不那么難了。XY方向相鄰像素的高度相減就是兩條正交的切向量,叉乘外加左/右手定則就獲得法線。或者更精確點(diǎn),用八鄰域弄個(gè)邊緣檢測(cè)算子(sobel、拉普拉斯之類 )[圖像處理里的空間域?yàn)V波],或者應(yīng)用斜坡法([水效果Ⅲ - 抖動(dòng)波] )來(lái)求切線、法線。

 2. 制作NormalMap
但是這樣還是挺麻煩的,既然都動(dòng)用額外的貼圖了,何不把這些與實(shí)現(xiàn)無(wú)關(guān)的預(yù)處理——作為結(jié)果的法線信息——都放進(jìn)紋理里呢?這就是Normal Map的思想起源。但是,誰(shuí)來(lái)做這樣的一張法線圖呢?敲定美工了。每個(gè)像素的RGB分別存儲(chǔ)該像素對(duì)應(yīng)法線的XYZ分量,只要把法線的分量由(-1,1)映射成(0,255)就可了。觀察一張法線圖,以藍(lán)色為主,是因?yàn)槌驁D面外的法線(0,0,1)都被編碼成(0,0,127)了(讀入OpenGL后即(0,0,0.5)),而圖上越紅的地方表明法線越向右,越綠的地方表明法線越向上,就可以理解了。總體來(lái)說(shuō),就是一張紫藍(lán)色的圖。怎么做這樣的圖呢?當(dāng)然最好是有一個(gè)工具,輸入原圖和高度圖后執(zhí)行上述的算法得出新圖了,事實(shí)上已經(jīng)有很多這類工具了(譬如比較著名的photoshop的NV插件Normal Map Filter,甚至不用高度channel也可[效果- -]),以下幾篇文章有詳細(xì)介紹,有興趣的可以看一看:
Tutorial On Normal Mapping (PHOTOSHOP [ENGLISH])
怎樣用PhotoShop創(chuàng)建Bump Map圖像 (PHOTOSHOP [CHINESE])
Nvidia Normal Map 插件參數(shù)之詳解 (PHOTOSHOP [翻譯])
GIMP normalmap plugin   (GIMP   [ENG])
關(guān)于NormalMap制作的原理,更詳細(xì)的可參考此文:Normalmap原理及去除接縫
 3. 切線空間(Tangent Space)
其實(shí)這個(gè)概念前文已經(jīng)提及了。每個(gè)像素根據(jù)高度圖生成的三軸坐標(biāo)系,就是被稱為切線空間坐標(biāo)系的東西,每個(gè)像素人手一個(gè)。可見(jiàn)Normal Map里面每個(gè)像素的法線就是定義在這個(gè)切線空間的。注意,這些法線是屬于像素的,而不是頂點(diǎn),我們平時(shí)用的法線是頂點(diǎn)法線,是定義在模型坐標(biāo)系的[亂彈OpenGL中的矩陣變換(上)] ,定義于所屬物件的唯一的局部坐標(biāo)系原點(diǎn)之上。而這些像素法線定義于切線坐標(biāo)系,其原點(diǎn)就在該像素上,切線副法線在法線的垂直平面上。


(表面依然是平的,但通過(guò)攪動(dòng)法線,使進(jìn)入我們眼睛的光線強(qiáng)度不一,模擬出凹凸面漫反射的特點(diǎn)。圖from GDNet)
應(yīng)用這些像素法線的目的無(wú)非是計(jì)算出該像素的OutPut顏色:col = baseColor * (amb + diffuse) + specular。這些都應(yīng)該在像素著色器(fragment shader)里進(jìn)行,因?yàn)槲覀円龅氖轻槍?duì)每個(gè)像素的處理[Shader快速?gòu)?fù)習(xí):Per Pixel Lighting(逐像素光照)] 。其中需要用到像素法線的是diffuse和specular(以前是用通過(guò)頂點(diǎn)法線線性插值而來(lái)的normal),法線分別與光線向量、半向量作點(diǎn)乘得到對(duì)應(yīng)因子。這個(gè)因子是個(gè)夾角cos而已,所以只要滿足像素法線與兩個(gè)向量單位化并在同一坐標(biāo)系下(而無(wú)論是哪個(gè)坐標(biāo)系),夾角就是一定的。這樣看來(lái),兩個(gè)選擇:
1. 把像素法線都從各自的切線空間轉(zhuǎn)到視圖空間來(lái),再點(diǎn)乘;
2.把光線向量、半向量從視圖空間轉(zhuǎn)到像素各自的切空間來(lái),再點(diǎn)乘。
很多文章一口咬定就是第2種好,原因是第1種要變換N個(gè)量;第2種只變換2個(gè)量。仔細(xì)分析,其實(shí)兩種選擇變換的次數(shù)是一樣的,都是2*N。說(shuō)第2種好,是因?yàn)椋?br>第1種必須在fragment shader里進(jìn)行,對(duì)象是從Normal Map讀出的像素法線和經(jīng)過(guò)線性插值而來(lái)的兩個(gè)向量,它們不是同一坐標(biāo)系的,按描述應(yīng)該是各像素法線乘以各自一個(gè)的變換矩陣,轉(zhuǎn)到視圖空間來(lái),但確實(shí)沒(méi)有其他的可提供構(gòu)筑這個(gè)矩陣的信息了,若有可能應(yīng)該就是另外的varying變量傳入了;
第2種可以選擇在vertex shader里進(jìn)行,但是能不能就在這里變換到切線空間呢?假設(shè)可以,那么得到的針對(duì)頂點(diǎn)的數(shù)值在光柵化-線性插值后能否滿足呢?
要回答這個(gè)問(wèn)題,還得考慮像素的切線空間和頂點(diǎn)的切線空間之間的關(guān)系。是的,頂點(diǎn)法線也可以變換到切線空間,但這有什么用呢?一步一步來(lái)吧。先考慮切線空間在OpenGL世界里的次元位置:

(from paulsprojects)
為什么是緊挨模型坐標(biāo)系呢?其實(shí)想想也能理解,在上面談及切線坐標(biāo)系的時(shí)候,并沒(méi)有廣闊的“世界”這個(gè)概念。只針對(duì)每個(gè)像素/頂點(diǎn),無(wú)疑是比模型坐標(biāo)系更狹隘的“世界觀”,所以那個(gè)位置是適合的(箭頭方向無(wú)所謂,坐標(biāo)系之間是可以相互轉(zhuǎn)換的)。其實(shí)對(duì)于某個(gè)具體的物體上的像素/頂點(diǎn),你可以考慮那是把模型空間的原點(diǎn)平移到該像素/頂點(diǎn)上,各模型坐標(biāo)系方向軸向量一起經(jīng)過(guò)旋轉(zhuǎn),使Z軸與像素/頂點(diǎn)的法線重合,XY軸分別與像素/頂點(diǎn)的切線副法線重合——這只是一個(gè)仿射變換而已,如同模型/世界/視圖空間之間的變換一樣。
如果你記得圖形學(xué)書(shū)上關(guān)于世界/視圖空間的變換矩陣的構(gòu)建的話,就更容易理解這樣的形式了。從切線空間到模型空間的變換矩陣(TBN矩陣MTBN)為:

 其中T,B,N是定義在模型空間的該像素/頂點(diǎn)的“切/副法/法向量”。稍微檢驗(yàn)一下,考慮某個(gè)三角面上的某個(gè)頂點(diǎn),其法線充當(dāng)切線空間的Z軸,在切線空間中表示為(0,0,1),在OpenGL里解釋為一個(gè)列向量(0,0,1)T,用上面的矩陣MTBN左乘該向量,得到(Nx,Ny,Nz)T,正是該向量在模型空間的表示。其他兩軸同理。說(shuō)明該矩陣把切線空間的坐標(biāo)系統(tǒng)轉(zhuǎn)換到模型空間了(一切變換都是在變換坐標(biāo)系[亂彈OpenGL中的矩陣變換(上)] )。當(dāng)然這是特例說(shuō)明,但確實(shí)這個(gè)矩陣包含仿射矩陣?yán)锏男D(zhuǎn)元素了(它只包含旋轉(zhuǎn),不設(shè)置平移,是因?yàn)槲覀冎恍枰鼇?lái)變換向量,向量是可以任意平移的,若要弄完整的4X4矩陣,第4列平移列就是該頂點(diǎn)模型坐標(biāo))。具體推導(dǎo)也不難,隨便Google一下"tangent space"就出來(lái)一堆了,而且都是基本一樣的推導(dǎo)過(guò)程,推一個(gè):Tangent Space。
其逆變換(矩陣MTBN-1)就可以把向量從模型空間變換到對(duì)應(yīng)頂點(diǎn)的切線空間了。如果你確保T,B,N兩兩垂直,這個(gè)正交矩陣的逆矩陣就是其轉(zhuǎn)置矩陣,這很理想。但萬(wàn)一你不確保這點(diǎn)(涉及到具體應(yīng)用,很多問(wèn)題的,后面會(huì)說(shuō)),就保證它們大致滿足三叉狀,用所謂的Gram-Schmidt 算法矯正:
T′ = T − (N · T)N
B′ = B − (N · B)N − (T′ · B)T′
反正最后得到的是這樣的形式——用它左乘光源向量和半向量,就得到對(duì)應(yīng)于該頂點(diǎn)切線空間的光源向量和半向量了:
T′x
B′x
NxT′y
B′y
NyT′z
B′z
Nz

為什么是頂點(diǎn)?因?yàn)檫@是你唯一能取得其切線/副法線/法線的東西了。這也是之前說(shuō)的選擇1不行的原因,在那張Normal Map里面已經(jīng)沒(méi)有任何法線副法線的確實(shí)信息了(只知道它們?cè)诜ň€垂直平面上),即使能通過(guò)別的方法取得(起碼要增加傳入數(shù)據(jù)),那要在fragment shader里每像素人手又計(jì)算一個(gè)矩陣,這就又是一個(gè)“計(jì)算量”(不是次數(shù))的問(wèn)題。所以還是用選擇2吧,也就是上面矩陣MTBN-1的討論。
選擇2的第一個(gè)問(wèn)題現(xiàn)在很清楚了:是可以的。只要取得頂點(diǎn)的切線/副法線/法線數(shù)據(jù)就能建立矩陣并變換光源向量和半向量,但結(jié)果是針對(duì)頂點(diǎn)的,我們需要的是針對(duì)像素的。光柵化線性插值這兩個(gè)向量,就是對(duì)應(yīng)像素的值,但這對(duì)嗎?直覺(jué)上不對(duì),但結(jié)果顯示這樣做沒(méi)有不妥(或者說(shuō)不會(huì)與真實(shí)所須差太多)。一般文章都沒(méi)有直接透視這個(gè)問(wèn)題,其實(shí)考慮一個(gè)矩形平面就露餡了,它四個(gè)頂點(diǎn)的TBN一致,變換得的光源向量也該一致,插值后得光源向量也該一致,但NormalMap中的像素有各自不同的切線空間系統(tǒng),光源向量不該一致的呃(雖則同向光源、不同法線足夠形成凹凸效果)。所以我對(duì)選擇2的第二個(gè)問(wèn)題保持疑問(wèn),有道深者請(qǐng)為鄙人指點(diǎn)迷津!
反正即使計(jì)算兩向量夾角的計(jì)算可能會(huì)有偏差,也不會(huì)太離譜,問(wèn)題到此結(jié)束。至于有的文章提及對(duì)diffuse的計(jì)算,光源向量插值后不須再歸一化的問(wèn)題(我嘗試過(guò),整體會(huì)變暗一點(diǎn)),就不深入了。注意我們?cè)趘ertex shader里變換到切線空間的是模型空間下的光源向量和視線向量(半向量是它們的和),而一般這兩個(gè)向量定義在視圖空間,所以之前還要做一個(gè)視圖空間->模型空間的變換(用ModelView矩陣的逆矩陣)。這是很多文章囫圇掉的一點(diǎn)。但如果你能取得視圖空間下的頂點(diǎn)TBN,也不需。因?yàn)榍芯€/副法線/法線若是被變換到視圖空間,則上面的TBN矩陣MTBN就是把東西從該頂點(diǎn)的切線空間變換到視圖空間(道理是一樣的),MTBN-1就能把視圖空間下的這兩個(gè)向量變換到該頂點(diǎn)的切線空間(參見(jiàn)下篇的代碼)。
 最后的問(wèn)題:怎么去取得模型空間下的頂點(diǎn)的切線,副法線,法線?連同shader實(shí)現(xiàn)代碼一起,我會(huì)在下篇談及,請(qǐng)留意了哦。

本文來(lái)源于ZwqXin http://www.zwqxin.com/ , 轉(zhuǎn)載請(qǐng)注明
原文地址:http://www.zwqxin.com/archives/shaderglsl/review-normal-map-bump-map.html


 

posted on 2010-11-29 17:53 狂爛球 閱讀(6004) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 圖形編程

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久久亚洲精品一区二区三区| 影音先锋中文字幕一区二区| 亚洲欧洲日本一区二区三区| 亚洲国产一区二区a毛片| 亚洲影院免费| 一区二区在线观看av| 91久久综合| 国产日韩av在线播放| 老色批av在线精品| 欧美连裤袜在线视频| 久久电影一区| 欧美精品一区二区三| 亚洲一区999| 欧美一级免费视频| 国产日韩精品一区| 亚洲人体偷拍| 国产一区二区三区四区| 日韩视频在线一区二区| 黄色小说综合网站| 亚洲私人影院| 亚洲免费激情| 久久裸体艺术| 午夜影院日韩| 欧美精品在线一区二区| 久久人人97超碰人人澡爱香蕉| 欧美高清一区二区| 久久精品日产第一区二区| 午夜精品理论片| 日韩视频永久免费| 久久精品色图| 欧美一区二区播放| 欧美伦理91i| 免费不卡在线视频| 国产精品私房写真福利视频| 日韩一二三在线视频播| 亚洲在线播放| 免费久久99精品国产自在现线| 午夜精品福利在线| 欧美激情性爽国产精品17p| 久久久噜噜噜| 国产精品日韩精品欧美精品| 亚洲黄色三级| 亚洲国产精品ⅴa在线观看| 午夜精品久久久久久久99樱桃 | 亚洲一区二区三区精品在线| 亚洲人成亚洲人成在线观看图片| 性久久久久久久久久久久| 亚洲一级网站| 欧美日韩亚洲一区二区三区在线观看| 免费不卡中文字幕视频| 国内久久婷婷综合| 欧美在线一级视频| 久久国产精品久久久久久久久久 | 久久黄色网页| 国产精品成人一区二区三区吃奶| 亚洲卡通欧美制服中文| 日韩视频在线一区二区| 欧美激情精品久久久六区热门| 欧美黄色免费| 亚洲精品免费在线播放| 欧美电影在线免费观看网站| 亚洲国产成人porn| 亚洲毛片在线观看| 欧美日韩精品欧美日韩精品| 亚洲人久久久| 亚洲午夜未删减在线观看| 欧美精品在线看| 99综合精品| 亚洲欧洲精品一区二区三区波多野1战4| 久久久综合激的五月天| 久久理论片午夜琪琪电影网| 国产热re99久久6国产精品| 一本色道**综合亚洲精品蜜桃冫| 国产精品久久久久秋霞鲁丝| 99视频有精品| 亚洲视频视频在线| 亚洲永久免费av| 欧美中日韩免费视频| 国产女人18毛片水18精品| 亚洲性夜色噜噜噜7777| 香蕉尹人综合在线观看| 国产日本欧美一区二区三区| 亚洲女人天堂成人av在线| 性欧美激情精品| 国产欧美69| 亚洲欧美怡红院| 亚洲国产成人精品视频| 99国产精品| 麻豆亚洲精品| 一本色道精品久久一区二区三区| 欧美日本国产在线| 在线亚洲观看| 午夜伦理片一区| 国产精品一区二区视频| 欧美一进一出视频| 久久影院午夜论| 久久国产综合精品| 欧美激情按摩在线| 亚洲精品国产日韩| 亚洲欧洲另类| 亚洲欧美福利一区二区| 国产乱码精品一区二区三区忘忧草| 久久久久久久久久久一区| 欧美精品在线视频观看| 国模私拍视频一区| 亚洲三级观看| 久久天堂av综合合色| 亚洲天堂av在线免费观看| 欧美一级免费视频| 久久永久免费| 狠狠色综合色综合网络| 亚洲一区二区视频在线| 欧美www视频| 久久久999| 亚洲丶国产丶欧美一区二区三区 | 亚洲精品韩国| 蘑菇福利视频一区播放| 亚洲成人原创| 欧美 日韩 国产在线 | 一区二区三区国产盗摄| 欧美成人免费全部| 亚洲精品国产精品乱码不99| 女主播福利一区| 欧美成人精品在线观看| 亚洲人成啪啪网站| 亚洲黄网站在线观看| 美女亚洲精品| 一区二区日韩精品| 一区二区三区国产在线观看| 国产精品嫩草久久久久| 亚洲欧美第一页| 午夜国产不卡在线观看视频| 国产欧美精品在线| 久久久久免费视频| 久热re这里精品视频在线6| 亚洲麻豆av| 欧美一区在线直播| 午夜日韩视频| 欧美一区二区三区喷汁尤物| 激情综合色丁香一区二区| 欧美高清视频一二三区| 欧美视频一区二区三区…| 翔田千里一区二区| 久久精品一区二区三区不卡| 亚洲国产另类久久精品| 日韩视频在线永久播放| 国产精品亚洲аv天堂网 | 久久精品麻豆| 国产午夜精品一区理论片飘花| 亚洲精品视频啊美女在线直播| 亚洲六月丁香色婷婷综合久久| 日韩视频在线一区二区| 国产一区欧美| 亚洲精品在线视频| 国内成人自拍视频| 亚洲经典三级| 国内精品久久久久国产盗摄免费观看完整版 | 久久精品亚洲精品国产欧美kt∨| 国产精品老牛| 亚洲成人中文| 国产精品人成在线观看免费| 农夫在线精品视频免费观看| 羞羞漫画18久久大片| 亚洲黄色片网站| 亚洲午夜一区二区三区| 在线成人黄色| 亚洲天堂男人| 亚洲国产综合91精品麻豆| 欧美国产欧美综合| 欧美另类人妖| 欧美激情第1页| 国产欧美一级| 一区二区三区四区国产| 亚洲精品一品区二品区三品区| 亚洲欧美视频一区二区三区| 黑人极品videos精品欧美裸| 一区二区三区高清视频在线观看 | 永久久久久久| 性色av一区二区三区在线观看| 99视频一区二区三区| 噜噜噜噜噜久久久久久91| 久久国产精品久久久久久| 欧美日韩在线观看视频| 亚洲高清一区二| 亚洲国产成人91精品 | 久久人91精品久久久久久不卡| 国产精品一香蕉国产线看观看| 99re成人精品视频| 欧美视频一区二区三区…| 亚洲人成亚洲人成在线观看| 国产自产高清不卡| 美日韩在线观看| 黄色亚洲大片免费在线观看| 一本久道久久综合狠狠爱| 亚洲欧洲精品成人久久奇米网| 亚洲欧美三级伦理| 免费在线观看成人av| 亚洲福利视频三区| 国产在线精品一区二区中文| 久久精品国产精品 |