unity shader学习笔记(一)——基础光照之标准光照模型定义

来源:互联网 发布:下沙淘宝代运营骗局 编辑:程序博客网 时间:2024/04/30 04:02

标准光照模型

标准光照模型只关心直接光照(direct light)。它把进入摄像机的光照分为4个部分:

  • 自发光(emissive),这部分用于给定一个方向时,物体表面会向这个方向产生多少的光,当没有使用全局光照时,自发光物体不会照亮周围物体,只是本身看起来更亮而已。
  • 高光反射(specular),这个部分用于描述当光线从光源照到物体表面时,物体镜面反射产生的光。
  • 漫反射(diffuse)这个部分是光线从光源照到物体表面时,物体向各个方向产生的光。
  • 环境光(ambient)这个部分用来描述其他间接的光。

标准光照模型公式

1.环境光

  在标准光照模型中,环境光通常会比较简单,就是给定的一个全局变量,就是说场景中所有物体都使用同一个环境光。

2.自发光

  标准光照模型中自发光可以直接使用材质的颜色。(Unity5中的全局光照系统可以模拟自发光物体对周围物体的影响)

3.漫反射

  漫反射可使用兰伯特定律(Lamberts Law),即反射光线的强度与表面法线和光源方向之间的夹角的余弦成正比。计算公式如下:
       
        这里写图片描述 
         
  其中LC(Light Color)是光照颜色和强度,MD(Material Diffuse)是材质的漫反射颜色,N(Normal)是表面法线向量,L(Light)是光源的单位矢量。max函数是为了防止法线和光源点乘结果为负,可防止物体被后面的光照照亮。
  漫反射还可以通过一种兰伯特定律的视觉加强模型半兰伯特光照模型来计算,半兰伯特光照模型没有使用max函数来防止法线和光源方向的点乘为负的情况,而是对其结果进行了一个X倍的缩放再加上一个Y大小的偏移大多数情况下,x和y为0.5。计算公式如下:
       
        这里写图片描述
       
  这样就可以把法线和光源方向的点乘的结果范围从[-1, 1]映射到[0, 1]。就是兰伯特光照模型中,对物体背面的结果会映射到同一个值,即0;而在半兰伯特光照模型中,背面也是有明暗变换,会映射到不同的值。
  

4.高光反射

  计算高光反射需要知道表面法线、视角方向、光源方向、反射方向,其中反射方向可以通过其他三个向量计算得到。计算公式如下:
       
       这里写图片描述
       
  这样就可以使用Phong模型来进行计算高光反射。计算公式如下:
       
        这里写图片描述
       
  其中,V(View)是视角方向,MS(Material Spscular)是材质的高光反射颜色,MG(Material Gloss)是材质的反光度(Shininess)。同样,这里也要防止V*R的结果为负。
  Blinn提出了一个相对简单的方法来得到类似的效果。他的思想就是不计算反射方向R。他计算了一个新的矢量H,是通过V和L取平均再归一得到的。即:
       
        这里写图片描述
       
  所以,Blinn-Phong模型的公式如下:
       
        这里写图片描述
       
  在摄像机和光源距离物体足够远的情况下,Blinn-Phong模型会快于Phong模型,因为H将是一个常量。当V或者L不是定值的时候,Phong模型反而会更快一点。

光照模型计算着色器

光照模型一般可以在以下两种着色器中计算:

  • 片元着色器:也叫逐像素光照(per-pixel lighting)。一般以每个像素为基础,得到它的法线(可以是对顶点法线插值得到,也可以从纹理法线中采样得到),然后进行光照模型计算。
  • 顶点着色器:也叫逐顶点光照(per-vertex lighting)。是在每个顶点上计算光照,然后在渲染图元内部进行线性插值,最后输出成像素颜色。

由于顶点数目远小于像素数目,因此逐顶点光照的计算量要小于逐像素光照。但是,由于逐顶点光照依赖于线性插值来得到像素光照,所以当光照模型中有非线性的计算时(计算高光反射),逐顶点就会出问题。而且由于逐顶点光照会在渲染图元内部对顶点颜色进行插值,会导致渲染图元内部颜色总是暗于顶点处的最高颜色值,这在某些情况下会产生明显的棱角现象。
  

阅读全文
0 0
原创粉丝点击