Unity shader学习之高光反射光照模型

高光反射光照模型的公式如下:

  Cspecular = Clight * mspecular * max(0, dot(v, r))gloss

要计算高光反射需要知道4个参数:入射光线颜色Cspecular,材质高光反射系数gloss,视角方向v和反射方向r

其中r可由cg函数reflect(i, n)求得。

转载请注明出处:http://www.cnblogs.com/jietian331/p/7088297.html

逐顶点高光反射shader如下:

 1 Shader "Custom/Specular Vertex-Level"
 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                 fixed4 color : COLOR;
35             };
36 
37             fixed4 _Diffuse;
38             fixed4 _Specular;
39             float _Gloss;
40                         
41             v2f vert (appdata v)
42             {
43                 v2f o;
44                 o.vertex = UnityObjectToClipPos(v.vertex);
45 
46                 // specular
47                 float3 lightDir = ObjSpaceLightDir(v.vertex);
48                 lightDir = normalize(lightDir);
49                 float3 nor = normalize(v.normal);
50                 float3 refLightDir = reflect(-lightDir, nor);
51                 refLightDir = normalize(refLightDir);
52                 float3 viewDir = ObjSpaceViewDir(v.vertex);
53                 viewDir = normalize(viewDir);
54                 float d = max(0, dot(refLightDir, viewDir));
55                 float3 specColor = _LightColor0.rgb * _Specular.rgb * pow(d, _Gloss);
56 
57                 // diffuse
58                 float3 diffuseColor = _LightColor0.rgb * _Diffuse.rgb * max(0, dot(lightDir, nor));
59 
60                 float3 c = specColor + diffuseColor + UNITY_LIGHTMODEL_AMBIENT.rgb;
61 
62                 o.color = float4(c, 1);
63 
64                 return o;
65             }
66             
67             fixed4 frag (v2f i) : SV_Target
68             {
69                 return i.color;
70             }
71             ENDCG
72         }
73     }
74 }
Custom/Specular Vertex-Level

逐像素高光反射shader如下:

 1 Shader "Custom/Specular Fragment-Level"
 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 refLightDir = reflect(-lightDir, worldNormal);
58                 refLightDir = normalize(refLightDir);
59                 float3 viewDir = UnityWorldSpaceViewDir(i.worldPos);
60                 viewDir = normalize(viewDir);
61                 float d = max(0, dot(refLightDir, viewDir));
62                 float3 spec = _LightColor0.rgb * _Specular.rgb * pow(d, _Gloss);
63 
64                 // diffuse
65                 float3 diff = _LightColor0.rgb * _Diffuse.rgb * max(0, dot(lightDir, worldNormal));
66 
67                 float3 c = spec + diff + UNITY_LIGHTMODEL_AMBIENT.rgb;
68                 return fixed4(c, 1);
69             }
70             ENDCG
71         }
72     }
73 }
Custom/Specular Fragment-Level

效果分别如下:

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