Unity Shaders and Effects Cookbook (3-5) 金屬軟高光
阿新 • • 發佈:2019-01-07
書上這一節看得我頭昏腦脹,數學渣表示自理不能…… 而且也不瞭解這個效果的實際意義。
先記錄下來,後面真正看懂了再來補充詳細理論。
通過一張紋理貼圖,定義高光的形狀,利用到的紋理貼圖有三種
這裡並不是把紋理 UV對映。而是讀取了 R通道值。
這幾張圖都是黑白的,也就是說,畫素的一個點的 RGB 是相同值,所以 讀取 R 或者 讀取 G、B都是同等的。
著色器程式碼為高光生成了一些粗糙度值。
然後這節利用菲涅爾法則,當我們的視線剛好正對著物體表面的時候,會幫我們遮蔽高光。
轉自 http://blog.csdn.net/huutu http://www.thisisgame.com.cn
這一節的完整Shader程式碼:
Shader "CookBookShaders/Metallicsoft" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _MainTint ("Diffuse Tint",Color)=(1,1,1,1) _RoughnessTex("Roughness Texture",2D)="white"{} _Roughness("Roughness",Range(0,1))=0.5 _SpecularColor("Specular Color",Color)=(1,1,1,1) _SpecularPower("Specular Power",Range(0,30))=2 _Fresnel("Fresnel",Range(0,1.0))=0.05 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Metallicsoft sampler2D _MainTex; float4 _MainTint; sampler2D _RoughnessTex; float _Roughness; float4 _SpecularColor; float _SpecularPower; float _Fresnel; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { half4 c = tex2D (_MainTex, IN.uv_MainTex) * _MainTint; o.Albedo = c.rgb; o.Alpha = c.a; } inline fixed4 LightingMetallicsoft(SurfaceOutput s,fixed3 lightDir,half3 viewDir,fixed atten) { //先計算出來所有的漫反射以及視點相關的向量; float3 halfVector=normalize(lightDir + viewDir); float NdotL=saturate(dot(s.Normal,normalize(lightDir))); float NdotH_raw=dot(s.Normal,halfVector); float NdotH = saturate(dot(s.Normal,halfVector)); float NdotV=saturate(dot(s.Normal,normalize(viewDir))); float VdotH=saturate(dot(halfVector,normalize(viewDir))); //生成一些粗糙度值,然後從紋理中讀取高光形狀 float geoEnum=2.0*NdotH; float3 G1=(geoEnum * NdotV)/NdotH; float3 G2=(geoEnum * NdotL)/NdotH; float3 G= min(1.0f,min(G1,G2)); float roughness=tex2D(_RoughnessTex,float2(NdotH_raw * 0.5 +0.5,_Roughness)).r; //菲涅爾準則;當我們視線正好對著物體表面時,會幫我們遮蔽高光; float fresnel=pow(1.0-VdotH,5.0); fresnel*=(1.0-_Fresnel); fresnel+=_Fresnel; //組合計算高光值; float3 specular=float3(fresnel * G * roughness * roughness) * _SpecularPower; //漫反射 加上 高光 float4 c; c.rgb=(s.Albedo * _LightColor0.rgb * NdotL)+(specular * _SpecularColor.rgb)*(atten * 2.0f); c.a=s.Alpha; return c; } ENDCG } FallBack "Diffuse" }
測試效果
示例工程下載:
http://pan.baidu.com/s/1bpDfEpT