Unity Shader 入门精要 - 基础光照

Unity Shader 入门精要 - 基础光照

    • 基础知识
    • Lambert模型:
    • Half Lambert模型:
    • Phong模型:
    • Blinn-Phong模型:

基础知识

使用辐照度(irradiance)来量化光,通过计算垂直于光源方向l的单位面积上单位时间内穿过的能量来得到。当物体表面与光的方向不垂直时,使用光源方向l与表面法线n之间的余弦值来计算。
Unity Shader 入门精要 - 基础光照_第1张图片
可知 s = d/cosθ (d和s构成直角三角形,两个锐角分别为a和b,可知θ+a=90,a+b=90,所以b=θ,cosθ = d/s),所以辐照度和cosθ 成正比,而 θ 可以由法向量n与光源方向l的点乘来计算。

光线与物体相交之后的结果是散射(scattering)和吸收(absorption),散射有两种方向,一种是折射(refraction)(透射,transmission),折射进入物体后还会与内部颗粒相交,一些会重新发射出表面,一些则被吸收。另外一种是反射(reflection)。

在光照模型中使用不同部分来计算它们:高光反射(specular)表示物体表面如何反射光线,漫反射(diffuse)表示有多少光线会被折射、吸收和散射出表面。使用出射度(exitance)来描述出线光线的数量和方向。辐照度和出射度满足线性关系,它们的比值就是材质的漫反射和高光反射属性。

标准光照模型把光线分成四个部分来计算:环境光(ambient)、自发光(emissive)、漫反射(diffuse)、高光反射(specular)。

  1. 环境光用来模拟间接光照,它通常是一个全局变量,计算式为
    cambient = gambient cambient = k * gambient,k(0
  2. 自发光直接使用材质的自发光颜色,cemissive = memissive
  3. 漫反射符合兰伯特定律:反射光线的强度与表面法线和光源方向之间的夹角的余弦值成正比,计算式为
    cdiffuse = (clight · mdiffuse) * cosθ(cosθ>0)cosθ等价于n·l,可化成 cdiffuse = (clight · mdiffuse) * max(0,n·I),clight是光源颜色或强度,mdiffuse是材质漫反射颜色,max防止点乘结果为负。或者是cdiffuse= k * Clight * max(0,n·l),k是漫反射系数。
  4. 高光反射 phong模型认为高光反射的光强和反射光线与视线的夹角相关,可以写成:
    cspecular = (clight·mspecular)max(0,v·r)gloss 或者 cspecular = k * clight * max(0,v·r)gloss,r是观察方向,gloss是材质的高光指数,数越大,亮点越小。

需要注意的是说的光源方向指的是从顶点到光源的方向

Lambert模型:

综合环境光和方向光源,可以写成
Idiffuse = cambient + cdiffuse

Half Lambert模型:

Lambert模型会使得物体背光面全黑,没有阴暗变化,失去了模型细节,Half Lambert模型改善了这一缺点,公式如下

cdiffuse = (clight · mdiffuse) (α(n·I) + β)

与原来相比,它没有防止点积为负值,而是对结果进行了α倍缩放再加上一个β大小的偏移,绝大多数情况下,α和β的值都为0.5,把点积范围从[ -1,1] 映射到了[0,1],在Lambert模型中,背面的点积结果都会映射到0,而在Half Lambert模型中,背面不同的点积会映射到不同的值上。需要注意的是它没有任何物理依据,只是一个视觉加强技术。

Phong模型:

Phong模型可以写成
Ispecular = cambient + cdiffuse + cspecular

Unity Shader 入门精要 - 基础光照_第2张图片

从上面可知高光反射的计算需要知道反射光线,而反射光线可以通过法线和入射光线来得到。
方法一:
Unity Shader 入门精要 - 基础光照_第3张图片
从图中可知
R = I + 2P
P = S - I

S是 I 在N上的投影,可得S的方向就是N归一化后的方向
S = |S| * (N/|N|)
模S则是I的模乘以cosθ
|S| = |I| * cosθ
cosθ可以由I和N求出
cosθ = I·N/|I||N|
可得
|S| = I·N/|N|
S = (I·N/|N|) * (N/|N|) = (I·N/|N|2) * N
N是单位向量,简化得
S = (I·N)N,

可得R = 2(I·N)N - I

方法二:
Unity Shader 入门精要 - 基础光照_第4张图片
入射角和反射角相等I与R长度也相等,三角形ION是等腰三角形,ON = 2S
R = 2S - I,其中S = (I·N)N,得R = 2(I·N)N - I。

Blinn-Phong模型:

不使用v和r的夹角来计算,避免计算反射光线,使用v和I的半角向量h和n的夹角来进行计算。
Unity Shader 入门精要 - 基础光照_第5张图片
h = v + I / |v + I|
cspecular = (clight·mspecular)max(0,n·h)gloss

夹角越小,h越靠近n,视线v越靠近反射光线r,当h和n的夹角为0,说明视线v处于反射光线r上

参考:
https://www.cnblogs.com/luxishi/p/6409716.html
https://www.cnblogs.com/graphics/archive/2013/02/21/2920627.html
https://www.cnblogs.com/graphics/archive/2010/08/03/1791626.html

你可能感兴趣的:(Unity,Shader,入门精要)