一、漫反射(diffuse)
这里我们使用 cdiffuse 来表示,这个部分用于描述从光源照射到模型表面时,该表面会向每个方向散射多少辐射量。由于是向各个方向散射的辐射度,所以在漫反射中,视角的位置是不重要的,应为反射是完全随机的,因此可以认为在任何反射方向上的分布都是一样的。但是,入射光线的角度很重要。
二、兰伯特光照模型
漫反射符合兰伯特定律(Lambert's law):反射光线的强度与表面法线和光源方向之间夹角的余弦值成正比。因此漫反射部分的计算如下:
其中 n 是表面法线, l 是指向光源的单位矢量, mdiffuse 是材质的漫反射颜色, clight 是光源颜色和强度。需要注意的是,我们需要防止法线和光源方向点乘的结果为负值,这样可以防止物体被从后面来的光源照亮。
三、半兰伯特光照模型
兰伯特光照模型有一个问题是,在光照无法到达的区域,模型的外光通常是黑的,没有任何的明暗变化,这会使模型的背光区域看起来就像一个平面一样,失去了模型细节的表现。为此,有一种改善技术被提出来,这就是半兰伯特(Half Lambert)光照模型。Valve公司在开发游戏《半条命》时提出了改善方案,在原兰伯特光照模型上进行了一个简单的修改,广义的半兰伯特光照模型的公式如下:
绝大多数情况下 α 、 β 的值都是0.5,即公式为:
通过这样的方式,我们可以把 n⋅l 的结果范围从 [−1,1] 映射到 [0,1] ,因此模型的背光区域也可以有敏感变化,不同的点积结果会映射到不同的值上。实际上半兰伯特光照模型没有任何的物理依据,它仅仅是一个视觉加强技术。
四、逐顶点兰伯特漫反射光照
逐顶点兰伯特漫反射光照效果:
逐顶点兰伯特漫反射光照.png
逐顶点兰伯特漫反射光照、逐像素兰伯特漫反射光照、逐像素半兰伯特漫反射光照效果:
逐顶点兰伯特漫反射光照、逐像素兰伯特漫反射光照、逐像素半兰伯特漫反射光照.png
兰伯特漫光照模型漫反射光公式:Id = Ip * Kd * N * L
Id:表面漫反射光颜色;
IP:入射光的光颜色;
Kd:漫反射系数 ( 0 ≤ Kd ≤ 1);
N为该点的单位法向量;
L为光单位向量;
五、逐像素兰伯特漫反射光照
逐像素兰伯特漫反射光照效果图:
逐像素兰伯特漫反射光照.png
逐顶点兰伯特漫反射光照、逐像素兰伯特漫反射光照、逐像素半兰伯特漫反射光照效果图:
逐顶点兰伯特漫反射光照、逐像素兰伯特漫反射光照、逐像素半兰伯特漫反射光照.png
兰伯特漫光照模型漫反射光公式:Id = Ip * Kd * N * L
Id:表面漫反射光颜色;
IP:入射光的光颜色;
Kd:漫反射系数 ( 0 ≤ Kd ≤ 1);
N:单位法向量;
L:单位光向量;
六、逐像素半兰伯特漫反射光照
半兰伯特
将兰伯特的计算公式 从限制[ 0 , 1 ]修改为 (n * l) * 0.5 + 0.5 ,防止背面没有光的地方过黑
逐像素半兰伯特漫反射光照效果:
逐像素半兰伯特漫反射光照.png
逐顶点兰伯特漫反射光照、逐像素兰伯特漫反射光照、逐像素半兰伯特漫反射光照效果:
逐顶点兰伯特漫反射光照、逐像素兰伯特漫反射光照、逐像素半兰伯特漫反射光照.png
半兰伯特漫反射公式:Id = Ip * Kd * (N * L * 0.5 + 0.5)
IP:入射光的光颜色;
Kd:漫反射系数 ( 0 ≤ Kd ≤ 1);
N:单位法向量;
L:单位光向量;
原理:由于兰伯特光照模型计算出模型背面的颜色为负数,模型背面会变成黑色,
改进为将[-1, 1]映射到[0, 1]上,即乘以0.5,再加上0.5。
七、Unity 兰伯特模型 漫反射
漫反射计算公式:
漫反射颜色 = 光线颜色 * 材质颜色 * 光线角度
推导:
n * l = cosθ * |n| * |l|
因为只需要角度所有 n和l可以归一化
n * l = cosθ
又因为cosθ存在负数,所以需要限制在0-1之间
diffuse = 光线颜色 * 材质颜色 * max(0, n * l)
八、Unity Phone模型 高光反射
β是反射光与相机方向之间的夹角
当β=0时,反射所有的光到摄像机,当β=1时没有反射光
反射光计算公式:
反射光 = 光线颜色 * 材质颜色 * ( 反射光强度 ^ 光泽度)
反射光强度计算公式:
反射光强度 = cosβ
r · v = |r| * |v| * cosβ
r 和 v取单位向量,所以
r · v = 1 * 1 * cosβ = cosβ
因为cosβ存在负数,所以要限制一下
反射光强度 = max(0,r · v) = max(cosβ)
反射光向量计算公式:
a = |l| * cosθ · n , n取单位向量
b = 2 * a = 2 * |l| * cosθ · n , l向量也单位向量
b = 2 * cosθ · n
b = 2 * (n · l) · n
因为 b = r + l,所以
r = b - l
r = 2 * (n · l) · n - l
最终反射光计算公式:
cosβ = r · v = (2 * (n · l) · n -l)
反射光强度 = 光线颜色 * 材质颜色 * ((2 * (n · l) · n -l) ^ 光泽度)