1. 程式人生 > >Unity shader學習之Blinn-Phong光照模型

Unity shader學習之Blinn-Phong光照模型

高光 ron mage tex cli dot 計算公式 ocl tro

Blinn-Phong光照模型不用計算反射方向,計算公式如下:

h = normalize(v + l);

Cspecular = Clight * mspecular * pow(max(0, dot(n, h), gloss))

轉載請註明出處:http://www.cnblogs.com/jietian331/p/7097201.html

shader如下:

 1 Shader "Custom/Specular Blinn-Phong"
 2 {
 3     Properties
 4     {
 5         _Diffuse ("Diffuse Color", Color) = (1,1,1
,1) 6 _Specular ("Specular Color", Color) = (1,1,1,1) 7 _Gloss ("Gloss", Range(8, 256)) = 8 8 } 9 SubShader 10 { 11 Tags { "RenderType"="Opaque" } 12 LOD 100 13 14 Pass 15 { 16 Tags { "LightMode"="ForwardBase" } 17 18 CGPROGRAM
19 #pragma vertex vert 20 #pragma fragment frag 21 22 #include "UnityCG.cginc" 23 #include "Lighting.cginc" 24 25 struct appdata 26 { 27 float4 vertex : POSITION; 28 float3 normal : NORMAL; 29 };
30 31 struct v2f 32 { 33 float4 vertex : SV_POSITION; 34 float3 worldPos : TEXCOORD0; 35 float3 worldNormal : TEXCOORD1; 36 }; 37 38 fixed4 _Diffuse; 39 fixed4 _Specular; 40 float _Gloss; 41 42 v2f vert (appdata v) 43 { 44 v2f o; 45 o.vertex = UnityObjectToClipPos(v.vertex); 46 o.worldNormal = UnityObjectToWorldNormal(v.normal); 47 o.worldPos = mul(unity_ObjectToWorld, v.vertex); 48 return o; 49 } 50 51 fixed4 frag (v2f i) : SV_Target 52 { 53 // specular 54 float3 worldNormal = normalize(i.worldNormal); 55 float3 lightDir = UnityWorldSpaceLightDir(i.worldPos); 56 lightDir = normalize(lightDir); 57 float3 viewDir = UnityWorldSpaceViewDir(i.worldPos); 58 viewDir = normalize(viewDir); 59 float3 halfDir = normalize(lightDir + viewDir); 60 float d = max(0, dot(halfDir, worldNormal)); 61 float3 spec = _LightColor0.rgb * _Specular.rgb * pow(d, _Gloss); 62 63 // diffuse 64 float3 diff = _LightColor0.rgb * _Diffuse.rgb * max(0, dot(lightDir, worldNormal)); 65 66 float3 c = spec + diff + UNITY_LIGHTMODEL_AMBIENT.rgb; 67 return fixed4(c, 1); 68 } 69 ENDCG 70 } 71 } 72 }

效果如下:

技術分享

這種光照模型的高光反射看起來更大,更亮一些。在實際渲染中,絕大多數情況會選擇 Blinn-Phong 光照模型,此種光照模型更符合實驗結果。

Unity shader學習之Blinn-Phong光照模型