US3S1L3-2——半兰伯特光照模型的逐片元光照

利用半兰伯特光照模型实现光照效果(逐片元光照)

半兰伯特光照模型的逐片元实现,和兰伯特一模一样,唯一的区别就是公式:

Color漫反射光照=Color光源×Color材质的漫反射×((标准化后物体表面法线向量标准化后光源方向向量)×0.5+0.5)Color_{漫反射光照} = Color_{光源} \times Color_{材质的漫反射} \times ((\overrightarrow{标准化后物体表面法线向量} \cdot \overrightarrow{标准化后光源方向向量}) \times 0.5 + 0.5)

具体Shader实现:

要注意,尽管半兰伯特光照模型改进了背光面的显示效果,我们为了光照效果更加自然还是会使用 UNITY_LIGHTMODEL_AMBIENT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
Shader "TeachShader/Lesson33"
{
Properties
{
_MainColor("MainColor", Color) = (1, 1, 1, 1)
}
SubShader
{
Tags { "LightMode" = "ForwardBase" }

Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"
#include "Lighting.cginc"

fixed4 _MainColor;

struct v2f
{
float4 pos : SV_POSITION;
float3 normal : NORMAL;
};

v2f vert (appdata_base v)
{
v2f v2fData;
v2fData.pos = UnityObjectToClipPos(v.vertex);
v2fData.normal = UnityObjectToWorldNormal(v.normal);

return v2fData;
}

fixed4 frag (v2f i) : SV_Target
{
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);

fixed3 color = _LightColor0 * _MainColor * (dot(i.normal, lightDir) * 0.5 + 0.5);
color = UNITY_LIGHTMODEL_AMBIENT + color;
return fixed4(color.rgb, 1);
}
ENDCG
}
}
}

显示效果(不同光照模型及他们对应的逐顶点光照和逐片元光照对比):

image