1. 程式人生 > >Unity-Shader-鏡面高光Phong&BlinnPhong-油膩的師姐在哪裏

Unity-Shader-鏡面高光Phong&BlinnPhong-油膩的師姐在哪裏

http erl range 反射光 all 諸多 實戰 常常 blog

【舊博客轉移 - 2016年4月4日 13:13

油膩的師姐:

以前玩過一款很火熱的端遊《劍靈》,劍靈剛出來的時候,某網頁遊戲廣告視頻中有句臺詞:“我不斷的在尋找,有你的世界在哪裏”,該廣告中的人物,音效都模仿了劍靈,而《劍靈》中的人物模型表面看上去油光發亮,所以就被網友改成了:“我不斷的洗澡,油膩的師姐在哪裏” 像這樣(皮膚表面的高光) 技術分享

這樣 技術分享

還有~ 這樣 技術分享 其實這是使用了鏡面反射著色,除了劍靈,其他很多高品質的AAA級遊戲也都使用了不同的鏡面高光,來增強視覺沖擊力和超現實感。

Phong高光類型

Phong光照模型是圖形學中表現很友好的高光類型,是一種非常常見的鏡面高光模型,從遊戲到電影都有諸多應用 鏡面反射跟漫反射的區別就是,漫反射的反射光是很分散的。鏡面反射的反射光會集中在一起, 視線離反射光越近,射入我們眼中的光也就越多,反之則看不到反射光 技術分享

Phong光照計算公式

Spec = pow( max(0 ,cos<R, V>), gloss) R:反射光向量 V:視線向量 gloss:鏡面的光滑程度,gloss越大就表示越光滑

Phong光照模型的Shader實現

Shader "lijia/Phong"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Specular("Specular", Range(1, 20)) = 1
        _SpecColor("SpecColor", Color) = (1
,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; float3 normal : TEXCOORD1; float3 lightDir : TEXCOORD2; float4 objPos : TEXCOORD3; }; sampler2D _MainTex; float4 _MainTex_ST; float4 _LightColor0;
float _Specular; float4 _SpecColor; v2f vert (appdata_full v) { v2f o; o.objPos = v.vertex; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); o.normal = v.normal; o.lightDir = ObjSpaceLightDir(v.vertex);//把光向量從世界空間轉成模型空間 return o; } fixed4 frag (v2f i) : SV_Target { float3 L = normalize(i.lightDir); float3 N = normalize(i.normal); float3 viewDir = normalize(ObjSpaceViewDir(i.objPos));//計算出視線 float diff = saturate(dot(L, N)); float3 reflection = normalize(2.0 * N * diff - L);//反射向量 float spec = pow(max(0, dot(reflection, viewDir)), _Specular); float3 finalSpec = _SpecColor.rgb * spec; //漫反射+鏡面高光+環境光 float3 finalLight = diff * _LightColor0 + finalSpec + UNITY_LIGHTMODEL_AMBIENT; fixed4 col = tex2D(_MainTex, i.uv); return col * float4(finalLight, 1); } ENDCG } } }

計算反射向量

Phong用到的是反射向量,計算反射向量的公式是 R = 2*N(dot(N, L)) - L 這個公式是根據向量的投影公式以及平行四邊形法則推導出來的 詳細步驟請看這篇文章,講的非常好 http://www.cnblogs.com/graphics/archive/2013/02/21/2920627.html

Blinn-phong光照模型

blinn是一個人的名字,他叫吉姆·布林,圖形學界的大牛,他發現了使用半角向量代替反射向量的計算方式 原理是通過視線向量跟光向量的半角向量代替反射向量 halfVector = normalize( L + V ); 這樣提高了代碼的計算效率,在視覺上也更加平滑,因此它成為了很多CG軟件中默認的光照模型 Shadre代碼跟Phong類似,我就不貼了

將Phone光照用到劍靈模型上的效果

技術分享

技術分享

右邊是Game視圖中加了後期效果的

參考資料:

《ShaderLab開發實戰詳解》

《Unity著色器和屏幕特效開發秘籍》

【淺墨Unity3D Shader編程】之十三 單色透明Shader & 標準鏡面高光Shader

Unity-Shader-鏡面高光Phong&BlinnPhong-油膩的師姐在哪裏