目錄
前言
一、圖片是否有法線貼圖的視覺區(qū)別
二、有視覺區(qū)別的原因
三、法線貼圖的作用
四、信息是如何存進(jìn)去的
五、自己寫一個Shader用到法線貼圖
六、注意事項
七、作者的話
前言
本小節(jié)會給大家解釋,什么是法線貼圖?為什么法線貼圖會產(chǎn)生深度?我們怎么自己寫一個shader,用上法線貼圖
一、圖片是否有法線貼圖的視覺區(qū)別
(如圖1所示)我們本來有一張普通的圖,看上去非常明顯是平面的,如果加了法線貼圖就會變成立體的感覺(如圖2所示)。


二、有視覺區(qū)別的原因
平面和立體最重要的區(qū)別是有深度,多了一個維度,
但是多的這個維度是怎么在2D圖片中顯示出來的?
答:有了不同的深度,光線照射的情況會不一樣。
例:如果我畫了一座山,放在桌面上,那么這個畫上面會接收到相同的光線。(如圖3所示)

哪里都能照到,隨便照,因為不存在遮擋關(guān)系,都是亮的。
但是如果是3D的山,光線就會存在遮擋問題,有些地方就照不到,有些地方能照到,照不到的地方接收到的就是黑色的光線,或者只能接到左邊來的光線,右邊來的光線只能接到一半。(如圖4所示)

因為有光線的加入,我們才會感覺東西立體了。
三、法線貼圖的作用
我們把是否能接收到光的信息提前存進(jìn)去,讓該亮的地方亮,該暗的地方暗。
四、信息是如何存進(jìn)去的
光線射過來的時候,都是一樣的,遇到物體以后會改變他的方向。
我們把物體每一個點反射的光線方向存起來,最后再畫出來就可以了。
由于每一個點都會有不同方向的反射光線(如圖5所示),我們把光線的方向都用向量表示,但,全部用數(shù)字記錄有點麻煩,比如(0.5,0.6,-0.2)

法線貼圖就解決了這個問題:
圖片剛好有rgb:
r(0-255)→x(-1,1)g(0-255)→y(-1,1)
b(0-255)→z(-1,1)
例如:圖一中的法線貼圖(如圖6所示)
圖6 圖1的法線貼圖 圖7 選取了一個點 此時,這里的rgb為(84,128,247),換成向量就為(-0.34,0.008,0.97)
同樣(-0.34,0.008,0.97)換成rgb就是(84,128,247),正反都成立。
那么就可以把一大堆信息,變成一個圖片,想知道這點的光線信息,就去讀它的顏色。
以前我們想看立體視角,必須要模型,現(xiàn)在,我們只需要法線貼圖,就很省性能。但是,有個缺點,就是如果看影子,它還是正圓的,畢竟是貼圖造出來的幻覺,并不是真凹進(jìn)去了。

PS:為什么法線貼圖都是藍(lán)色的?
如圖5所示,決定光線是否會穿出紙面,被人眼看見的是z向量,z向量對應(yīng)的是b(0-255)藍(lán)色,大部分顏色都需要被我們看見,所以法線貼圖大多是藍(lán)色的。
五、自己寫一個Shader用到法線貼圖
Shader "Custom/006_nomalMap"
{
Properties
{
//首先先放兩個圖片進(jìn)來
//正常圖片
_MainTexture ("Texture", 2D) = "white" {}
//法線圖片
_MainNormal ("NormalTexture",2D) = "bump" {}
}
SubShader
{
CGPROGRAM
//引入已有的腳本
#pragma surface surf Lambert
//把上面資源里的圖,接收到shader語法里
//注意事項:名字必須和上面一樣
sampler2D _MainTexture;
sampler2D _MainNormal;
//待會我們需要把 圖片數(shù)據(jù) 轉(zhuǎn)換成 坐標(biāo)數(shù)據(jù)
struct Input
{
//準(zhǔn)備接受主圖的坐標(biāo)數(shù)據(jù)
float2 uv_MainTexture;
//準(zhǔn)備接收法線圖片的坐標(biāo)數(shù)據(jù)
float2 uv_MainNormal;
//注意事項:名字只能是上面的名字前面加uv
};
//寫了一個方法,把shader原有的數(shù)據(jù)引入進(jìn)來 把輸出的接口也拿過來
void surf(Input IN, inout SurfaceOutput o )
{
//改反射的內(nèi)容 獲取圖片上的rgba改成坐標(biāo)信息,但我們只要rgb的數(shù)據(jù)
o.Albedo = tex2D(_MainTexture,IN.uv_MainTexture).rgb;
//改法線信息 //這里因為rgb的數(shù)據(jù)是(0,1),但法線數(shù)據(jù)是(-1,1),所以需要二次轉(zhuǎn)換一下
o.Normal = UnpackNormal(tex2D(_MainNormal,IN.uv_MainNormal));
//備注:這里的unpackNormal的全稱是UnpackNormalFromTexture,
// 意思是,從texture恢復(fù)(解壓)成Normal
}
ENDCG
}
FallBack "Diffuse"
}
六、注意事項
在使用法線貼圖的時候,注意圖片格式必須是法線格式。(如圖9所示)文章來源:http://www.zghlxwxcb.cn/news/detail-852017.html

七、作者的話
鴿了大家這么久,真對不住,主要是最近一直997,現(xiàn)在稍微閑一點點了,作者立馬接上了。非常感謝大家的支持,愛你們喲~文章來源地址http://www.zghlxwxcb.cn/news/detail-852017.html
到了這里,關(guān)于Unity | Shader基礎(chǔ)知識(第十一集:什么是Normal Map法線貼圖)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!