Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

半兰伯特光照模型

一、必备知识

单位向量的点乘范围

根据数学公式我们知道 假设单位向量 A 和 B,他们的点乘结果是 A·B=|A|*|B|*cosθ 因为 cosθ 的范围是(-1,,1)之间,所以单位向量的点乘范围也是(-1,1)

二、半兰伯特光照模型的来历和原型

半兰伯特光照模型是基于 兰伯特光照模型的基础上进行改进的 它没有任何物理依据,只是一个视觉加强技术 它出现的主要原因是因为我们在使用兰伯特光照模型时,在背光面是全黑的 而半兰伯特光照模型可以让背光面也可以有明暗变化

半兰伯特光照模型没有特定的发明者 它是图形学领域的众多研究人员的共同贡献 研究人员们经常相互借鉴和改进现有模型 以更好的模拟真实世界中的光照和材质反射

原理 和兰伯特光照模型的理论是一样的 认为漫反射的强度仅仅与入射光的 方向和反射点处表面法线的夹角的余弦值成正比

三、半兰伯特光照模型的公式

1.公式

漫反射光照颜色 = 光源的颜色 * 材质的漫反射颜色 * ((标准化后物体表面法线向量 · 标准化后光源方向向量) * 0.5 + 0.5)

2.对比

兰伯特光照模型 :光源的颜色 * 材质的漫反射颜色 * max(0 , 标准化后物体表面法线向量 · 标准化后光源方向向量) 后半部分 点乘小于 0 部分会变成 0 半兰伯特光照模型:光源的颜色 * 材质的漫反射颜色 * ((标准化后物体表面法线向量 · 标准化后光源方向向量) * 0.5 + 0.5) 后半部分 点乘小于 0 部分都会变成 0~0.5

四、顶点着色器实现

1.代码部分

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
Shader "Unlit/Hanf_Lambert"
{
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;
fixed3 color:COLOR;

};

v2f vert (appdata_base v)
{
v2f v2fData;
v2fData.pos = UnityObjectToClipPos(v.vertex);
float3 normal = UnityObjectToWorldNormal(v.normal);
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
v2fData.color = UNITY_LIGHTMODEL_AMBIENT.rgb + _LightColor0.rgb * _MainColor *(dot(normal,lightDir)*0.5+0.5);
return v2fData;
}

fixed4 frag (v2f i) : SV_Target
{
return fixed4(i.color.rgb,1);
}
ENDCG
}
}
}

2.实现效果

实现效果图

四、片元着色器实现

1.代码部分

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
Shader "Unlit/Harf_LambertF"
{
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"
float4 _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 = _MainColor.rgb * _LightColor0.rgb * (dot(i.normal,lightDir)*0.5+0.5);
color = UNITY_LIGHTMODEL_AMBIENT.rgb + color;
return fixed4(color.rgb,1);
}
ENDCG
}
}
}

2.实现效果

实现效果图

评论