UnityShader 漫反射(Diffuse)光照模型
主要實現(xiàn)的的Phone模型,即逐頂點光照模型。
所謂漫反射
指的就是對于那些被物體表面隨機散射到各個方向的輻射度進行建模,它的效果是接近于現(xiàn)實中的漫反射,但它的反射是完全隨機的,任何反射方向的分步都是一樣的。
漫反射的計算公式如下
C.diffuse = (C.light · M.diffuse)max(0,N·L)
計算漫反射需要知道4個參數(shù):入射光線顏色與強度C.light,材質的漫反射系數(shù)M.diffuse,表面法線N,光源方向L。max的函數(shù)意義在于將括號內的值截取在[0,1]范圍內,如果是一個矢量,則對它的每一個分量都這么做。
接下來是代碼部分

在properties中聲明一個color類型的屬性,初始值設置為(1,1,1,1),即白色。
在SubShader語義塊中定義一個Pass語義塊,Pass語義塊內就是一個渲染流程代碼
首先使用Tags指明該pass的光照模式,只有定義了正確的LightMode,才能得到Unity內的內置光照變量,例如_LightColor0.
使用CGPROGRAM? ENDCG包圍Cg代碼片,指定編譯的頂點著色器代碼和片元著色器代碼的名稱,以及包含Unity的內置文件Lighting.cginc,為了使用properties中聲明的屬性,還需要定義一個和該屬性(fixed4)相匹配的變量_Diffuse
聲明a2v與v2f的結構體,a2v是application to vertex的簡寫,v2f則是vertex to fragment的簡寫。其中a2v包含了4位數(shù)的vertex變量與3位的法線normal變量,v2f則包含了4位浮點數(shù)的方向pos變量,三位數(shù)的color變量。
接下來是頂點著色器vert?
首先聲明返回值 o
通過UnityObjectToClipPos函數(shù)將頂點位置從模型空間轉換到齊次剪裁空間
使用UNITY_LIGHTMODEL_AMBIENT.xyz得到環(huán)境光部分變量
關鍵的來了,計算漫反射需要世界空間下的法線向量與光源方向的點乘,而此時的法線矢量還處于模型空間下,所以需要使用mul函數(shù)對v.normal進行轉化,使用的轉換矩陣則是模型空間到世界空間的轉換矩陣的逆矩陣,即(float3x3)unity_WorldToObjetct。通過它與v.noraml的矩陣乘法運算,可以得出法線矢量在世界坐標系下的方向。
得到了世界空間下的法線與光源方向后,對其進行歸一化得到點乘,使用saturate函數(shù)對其取值進行限制在[0,1]范圍內,然后再使用_LightColor0.rgb,即光源的顏色與強度與_Diffuse.rgb材質漫反射顏色相乘,即可求得最終的漫反射光照部分。
最后在用求得的漫反射光照diffuse與環(huán)境光ambient相加,即可得到漫反射效果。
最后的Fallback“Diffuse”是與SubShader同級的,它本身也類似與SubShader。
最后的效果如下
