Unity Shader入门精要 | 基础光照

标准光照模型

标准光照模型(又称为Phong模型)只关心直接光照,即直接照射到物体表面后,经过一次反射进入摄像机的光线,它将这些光线分为四个部分:

  • 自发光(emissive):表面本身会朝着给定方向发射的辐射量
  • 高光反射(specular):镜面反射的辐射量
  • 漫反射(diffuse):向四周散射的辐射量
  • 环境光(ambient):其他所有间接光照

环境光(ambient)

通常在场景中使用一个全局变量:
c a m b i e n t = g a m b i e n t c_{ambient} = g_{ambient}


自发光(emissive)

使用该材质的自发光颜色:
c e m i s s i v e = m e m i s s i v e c_{emissive} = m_{emissive}

在实时渲染中,自发光的表面不会照亮周围的表面,即这个物体并不会被当成光源。


漫反射(diffuse)

Lambert模型

漫反射光照符合兰伯特定律(Lambert’s law),反射光线的强度与表面法线和光源方向之间夹角的余弦值成正比,因此漫反射部分的计算如下:
c d i f f u s e = ( c l i g h t m d i f f u s e ) m a x ( 0 , n I ) c_{diffuse} = (c_{light}\cdot m_{diffuse})max(0,n\cdot \Iota)

其中, n n 是表面法线, I \Iota 是指向光源的单位矢量, m d i f f u s e m_{diffuse} 是材质的漫反射颜色, c l i g h t c_{light} 是光源颜色。需要防止法线和光源方向点乘的结果为负值,这样可以防止物体被从后面来的光源照亮。

半兰伯特模型

待补充


高光反射(specular)

计算高光反射需要表面法线、视角方向、光源方向、反射方向等数据。
PHong

反射方向可以经过计算得到:
r = 2 ( n ^ I ) n ^ I r = 2(\hat{n}\cdot \Iota)\hat{n}-\Iota

接着用Phong模型计算高光反射的部分:
c s p e c u l a r = ( c l i g h t m s p e c u l a r ) m a x ( 0 , v ^ r ) m g l o s s c_{specular} = (c_{light}\cdot m_{specular})max(0,\hat{v}\cdot r)^{m_{gloss}}

其中 m g l o s s m_{gloss} 是材质的光泽度,它控制高光区域的亮点大小, m s p e c u l a r m_{specular} 是材质的高光反射颜色, c l i g h t c_{light} 是光源的颜色和强度。

Blinn-Phong模型

Blinn提出一个修改方法来避免计算反射方向 v ^ \hat{v} ,为此引入了新的矢量 h ^ \hat{h} ,对 v ^ \hat{v} I ^ \hat{\Iota} 取平均后再归一化来得到:
h ^ = v ^ + I v ^ + I \hat{h}= \frac{\hat{v}+\Iota}{\left|\hat{v}+\Iota\right|}

然后使用 n ^ \hat{n} h ^ \hat{h} 之间的夹角来计算,如下所示:
Blinn
Blinn模型公式:
c s p e c u l a r = ( c l i g h t m s p e c u l a r ) m a x ( 0 , n ^ h ^ ) m g l o s s c_{specular} = (c_{light}\cdot m_{specular})max(0,\hat{n}\cdot\hat{h})^{m_{gloss}}



逐像素还是逐顶点

逐像素是在片元着色器中计算光照模型,逐顶点则是在顶点着色器中计算。

逐像素以每个像素为基础,得到法线(可以是对顶点法线插值,或者对法线纹理采样)然后进行计算,这种技术称为Phong着色(Phong Shading)

逐顶点的方法称为高洛德着色(Gouraud Shading),在图元内部进行线性插值,计算量比逐个像素计算要小,但是对于非线性的情况会有比较明显的问题。



Unity内置函数

在这里插入图片描述 内置函数得到的方向需要归一化。