Unity shader学习之Blinn-Phong光照模型

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 光照模型,此种光照模型更符合实验结果。

原文地址:https://www.cnblogs.com/jietian331/p/7097201.html