17.ShaderLab基本光照模型
記錄記錄...
理論基礎(chǔ): Blinn-Phong反射模型
漫反射(Diffuse reflection)
高光(Specular highlights)
間接/環(huán)境光照(Ambient lighting)
1.漫反射-蘭伯特余弦定律(Lambert):

L是光源的向量,N是法線向量,I是光源強(qiáng)度。
漫反射 diffuse = I * cosθ
余弦定理 cosθ = L · N / (|L|*|N|)
由于L,N長度都為1, 消去|L|*|N|得
diffuse = L · N * I
排除負(fù)數(shù),得到最終公式
diffuse =max(0, L · N) * I
核心代碼
效果

逐頂點(diǎn)漫反射 完整代碼
參考: https://zhuanlan.zhihu.com/p/110326132
逐像素光照同理, 略
函數(shù)解釋
UnityObjectToWorldNormal 模型空間法線向量->世界空間向量
UnityObjectToClipPos 頂點(diǎn)坐標(biāo) 模型空間->齊次裁切空間
添加環(huán)境光照
此時(shí), 物體的背面是完全暗的,需要添加環(huán)境光照.
在原有基礎(chǔ)上加上ambient 則能有基礎(chǔ)亮度
2.高光反射

I是光源信息,r是反射方向,viewDir是視角方向,gloss是光滑度, n是法線向量。
高光反射? specular = I * max(0, r · viewDir)^gloss
反射方向? r=2(n*L)n ― L
或是使用Unity的函數(shù) r = reflect(-L,n)??
視角向量 viewDir = UnityWorldSpaceViewDir(i.worldPos)
頂點(diǎn)世界坐標(biāo) worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
核心代碼
函數(shù)介紹
reflect(-worldLightDir,worldNormal); ?反射方向 ?
UnityWorldSpaceViewDir 相機(jī)方向
saturate 相當(dāng)于max加clamp(0,1)
unity_ObjectToWorld 坐標(biāo)變換矩陣, 用于局部轉(zhuǎn)世界坐標(biāo)
效果

理解公式 specular = I * max(0, r · viewDir)^gloss? (默認(rèn)gloss>1)
r · viewDir 是向量的點(diǎn)乘, 向量都是經(jīng)過歸一化處理的
所以得到 r· v = |r|*|v|*cosθ = cosθ ,
相當(dāng)于, 反射角與視角向量夾角越小, cosθ越大, 亮度越大
反之, 夾角>90°, 則結(jié)果負(fù)數(shù), max后為0 , 就看不到高光
gloss相當(dāng)于衰減系數(shù), 系數(shù)越大, 光圈越小

逐像素高光反射 完整代碼