我所了解的法线贴图
兩篇文章
本文大多數(shù)內(nèi)容來自這兩篇文章,看完后基本明白了法線貼圖的種種細(xì)節(jié)。
凹凸映射
寫給笨人的法線貼圖原理
一些基本的概念
1.法線貼圖的定義
顧名思義,法線貼圖保存的是法線的信息貼圖。
2.用來干什么
用來進(jìn)行凹凸映射。
凹凸映射的目的是使用一張紋理來修改模型表面的法線,以便為模型提供更多的細(xì)節(jié)。這種方法不會(huì)真的改變模型的頂點(diǎn)位置,只是讓模型看起來好像是“凹凸不平”的,但可以從模型的輪廓處看出“破綻”。
有兩種主要的方法可以用來進(jìn)行凹凸映射:一種方法是使用一張高度紋理(height map)來模擬表面位移(displacement),然后得到一個(gè)修改后的法線值,這種方法也被稱為高度映射(height mapping);另一種方法則是使用一張法線紋理(normal map)來直接存儲(chǔ)表面法線,這種方法又被稱為法線映射(normal mapping)。盡管我們常常將凹凸映射和法線映射當(dāng)成是相同的技術(shù),但要知道它們之間的不同。
3.種類
世界空間下的法線紋理
模型空間下的法線紋理
切線空間下的法線紋理
對(duì)比不同的法線貼圖
首先按照不同的坐標(biāo)系得到了不同類型的法線貼圖。模型頂點(diǎn)的法線根據(jù)所處坐標(biāo)系的不同,在成圖后表現(xiàn)也是不同的。以模型法線貼圖和切線法線貼圖為例:
上圖 左邊: 模型空間下的法線紋理 右邊: 切線空間下的法線紋理
不同的顏色是因?yàn)榉ň€作為一個(gè)Vector3類型的需要轉(zhuǎn)換到2D的顏色,而通常來說我們可以把顏色的RGB看成一個(gè)坐標(biāo)系,這樣法線就對(duì)應(yīng)了一個(gè)RGB顏色。但是法線的范圍是[-1,1],而顏色是沒有賦值的,因此有以下的轉(zhuǎn)換過程。
法線紋理存儲(chǔ)的是表面的法線方向。由于法線方向的分量范圍在[-1, 1],而像素的分量范圍為[0, 1],因此我們需要做一個(gè)映射,通常使用的映射就是:
pixel=(normal + 1) / 2
這就要求,我們?cè)赟hader中對(duì)法線紋理進(jìn)行紋理采樣后,還需要對(duì)結(jié)果進(jìn)行一次反映射的過程,以得到原先的法線方向。反映射的過程實(shí)際就是使用上面映射函數(shù)的逆函數(shù):
normal=pixel × 2 - 1
1.world space normal map
一旦從貼圖里解壓出來后,就可以直接用了,效率很高.但是有個(gè)缺點(diǎn),這個(gè)world space normal 是固定了,如果物體沒有保持原來的方向和位置,那原來生成的normal map就作廢了。
世界坐標(biāo)下的頂點(diǎn)的法線是現(xiàn)成的,因此好用。不過如果進(jìn)入模型在U3D里面進(jìn)行了位置或者方向的轉(zhuǎn)換,那么在沒有轉(zhuǎn)換矩陣的情況下,法線信息就是錯(cuò)誤的,也就無法使用了。進(jìn)一步思考如果場(chǎng)景中存在大量的靜態(tài)模型,可以考慮用這個(gè)。
2.object space normal map
對(duì)于模型頂點(diǎn)自帶的法線,它們是定義在模型空間中的,因此一種直接的想法就是將修改后的模型空間中的表面法線存儲(chǔ)在一張紋理中,這種紋理被稱為模型空間的法線紋理(object-space normal map)。
對(duì)象空間的法線貼圖,這個(gè)貼圖中記錄的法線信息是基于模型空間的,因此數(shù)值是相對(duì)的,這樣模型在場(chǎng)景中是可以位移和旋轉(zhuǎn)的,只要在計(jì)算的時(shí)候乘上對(duì)應(yīng)的矩陣即可。而且從上面的圖里可以看到貼圖是彩色的,因?yàn)槟P蜕系捻旤c(diǎn)法線在這個(gè)空間中是朝各個(gè)方向的。
對(duì)象空間的法線貼圖比起世界空間的在使用了已經(jīng)有了很大的進(jìn)步,不過它仍舊有自己的局限性,就是這樣的貼圖還是依賴于模型本身。從其定義也可以看出來,它也是一種“絕對(duì)位置”。如果模型發(fā)生了形變,則這個(gè)貼圖的信息就是錯(cuò)誤的。從目前來看,我只能想到模型在場(chǎng)景中存在動(dòng)畫這個(gè)問題。
3.tangent space normal map
對(duì)于模型的每一個(gè)頂點(diǎn),它都有一個(gè)屬于自己的切線空間,這個(gè)切線空間的原點(diǎn)就是該頂點(diǎn)本身,而z軸是頂點(diǎn)的法線方向(n),x軸是頂點(diǎn)的切線方向(t),而y軸可由法線和切線叉積而得,也被稱為副切線(bitangent, b)或副法線。這種紋理被稱為是切線空間的法線紋理(tangent-space normal map)。
定義很好理解,從本質(zhì)上講切線空間的法線貼圖解決了模型變形的問題。因?yàn)樵诹硪粋€(gè)模型上的頂點(diǎn)的切線空間坐標(biāo)系里面,法線貼圖中的信息是可以使用的,它不依賴于模型本身、也不依賴于模型所處的坐標(biāo)系。
4.切線空間下的法線貼圖如何生成
以3DMAX為例,法線貼圖需要高模和低模配合,具體過程不說了,網(wǎng)上大把的視頻。
重點(diǎn)是法線貼圖的生成需要高模和低模,因?yàn)闆]有高模就不知道法線方向,沒有低模,就不知道高模上某點(diǎn)的法線對(duì)應(yīng)于低模上哪個(gè)點(diǎn)。
下面才是重點(diǎn),因?yàn)槎鄠€(gè)高模的面使用了同一個(gè)低模的面,因此在生成法線貼圖時(shí),高模不能使用自己的tangent space,而是使用低模的tangent space。這樣一些高模上的點(diǎn)的法線與低模面上的法線出現(xiàn)了不一致,你可以想象低模上的某個(gè)面上的法線指向一個(gè)方向,但是對(duì)應(yīng)了幾個(gè)高模的點(diǎn),可能一些點(diǎn)的法線與低模面的法線方向一樣,那么很好,完美融入低模的切線空間,顏色呈現(xiàn)出淡藍(lán)色。但是其它那些和低模面法線不一致的點(diǎn)的法線就產(chǎn)生了夾角,就造成了在切線法線貼圖上那些不是[0.5,0.5,1]色值的點(diǎn)。
低模上的這個(gè)tangent space,也必須與高模上的坐標(biāo)系tangent space。因?yàn)榈湍I系囊粋€(gè)面,可能對(duì)應(yīng)了高模上的幾個(gè)面(精度高),按照新方法每個(gè)面都有一個(gè)局部坐標(biāo)系,那對(duì)于低模上的每個(gè)面,高模因?yàn)榇嬖诤脦讉€(gè)面,就會(huì)出現(xiàn)好幾個(gè)局部坐標(biāo)系,這肯定是不行的。所以高模所用的tangent space,就是低模上的。生成法線貼圖,必定會(huì)確認(rèn)高模上哪些面都對(duì)應(yīng)低模上的哪個(gè)面,然后高模上的這幾個(gè)面的法線,都會(huì)轉(zhuǎn)換為低模這個(gè)面上所構(gòu)建的tangent space的坐標(biāo)。這樣,當(dāng)?shù)湍W冃螘r(shí),即三角面變化時(shí),它的tangent space也會(huì)跟著變化,保存在貼圖里的法線乘以低模這個(gè)面的tangent space到外部坐標(biāo)系的轉(zhuǎn)換矩陣即可得到外部坐標(biāo)。順便再提一點(diǎn),高模保存的這個(gè)法線,是高模上object space里的法線。
對(duì)于上述的內(nèi)容,這張圖做了很好的詮釋。
如何將高模的法線貼圖用在低模上
對(duì)于object space normal map,低模的object space坐標(biāo)系與高模中的object space坐標(biāo)系是重合的。所以不需要構(gòu)建,所以低模上某點(diǎn)才能直接用高模的法線替換自己的法線。
總結(jié)
- 上一篇: 关于抠图的一些文章方法收集
- 下一篇: 通过SQL自动添加流水号