Reference:

  • 冯乐乐《UnityShader入门精要》

光照在渲染中是很重要的一个环节,多数情况下,物体渲染的真实程度与光照有很大的关系。

在光学中,使用辐照度(irradiance)来量化光。光线从光源发射出来之后与物体相交会产生两种结果:散射(只改变光的方向,不改变光的密度与颜色,可分为折射或反射)或吸收。

一些与光照模型相关的向量:
观测方向(viewer direction):着色点往相机连线方向,通常记作v
表面法线方向(surface normal):在着色点上垂直于表面的方向,称作表面法线方向,通常记作n。
光线方向(light direction):着色点往光源连线方向,通常记作I

(一)光照类型


  • 漫反射:光线打到物体上均匀地向四周反射,由于漫反射为均匀反射,因此与观测方向无关,只与光线方向和表面法线方向间的夹角有光。根据兰伯特的余弦定律,物体接收光的“多少”和单位面积下物体表面法线方向与光照方向间夹角的余弦值相关。
  • Unity Bakery丢失光照贴图_游戏引擎

  • 漫反射的光照衰减:intensity(衰减值)光线在传播过程中,只考虑单位面积下,物体所能接收的能量与光线传播距离的平方成反比。
  • Unity Bakery丢失光照贴图_归一化_02

  • 高光反射:光的反射方向接近于镜面反射,其衰减程度取决于观察方向与反射方向的夹角。根据不同的模型(这里指Phong模型与Blinn-Phong模型,下面会讲到),高光反射的计算有些许不同,但高光反射的主要影响因素为物体表面法线方向、观测方向以及光线方向。
  • 环境光:物体接收来自环境反射而来的光,通常假设它们强度相同。环境光与直接光照方向、观测方向以及物体表面法线方向无关,因此环境光通常为一个常数。

Unity Bakery丢失光照贴图_归一化_03

  • 自发光:光线直接由光源进入相机而不经过任何反射,通常自发光表面不会照亮其他表面。

(二)基本光照模型

标准的光照模型通常被分为四个部分:自发光、环境光、漫反射以及高光反射。常见的光照模型有Phong反射模型与Blinn-Phong反射模型,而Phong模型与Blinn-Phong模型间的差别在于对高光反射的计算上。

Blinn-Phong反射模型(环境光+漫反射+高光反射):

  • 环境光:环境光通常被视作常量。
  • 漫反射:漫反射满足兰伯特定律,因此利用兰伯特定律可以对漫反射进行计算。

    由于余弦值可能取到0,而由于取小于0的值无物理意义,因此截取为0。

漫反射还可以利用半兰伯特模型进行计算,半兰伯特模型通过将整体的区间乘以0.5再加上0.5,使的最终的光照计算结果区间永远为在[0,1]之间。

  • 高光反射:

    Blinn-Phong模型引入了半角(光源方向与视线方向相加并归一化)的概念,计算半角向量与法线向量间的夹角,而Phong模型为直接计算反射方向与视线夹角,二者的效果区别不大,但Phong模型的消耗更大。

余弦指数的作用:由于高光通常集中于一个较小的点上,而单纯的余弦值具有较大的容忍度,因此对齐其通过指数的形式来控制其高光聚焦的大小。下图比较了余弦指数在1、2、8以及64之间的关系不同曲线关系。在Blinn-Phong模型中,指数通常范围在100-200。

Unity Bakery丢失光照贴图_Unity Bakery丢失光照贴图_04

下图可以看到在取不同指数时高光焦点的区别:

Unity Bakery丢失光照贴图_Unity Bakery丢失光照贴图_05

因此Blinn-Phong反射模型有如下表示:

Unity Bakery丢失光照贴图_Unity Bakery丢失光照贴图_06

(三)渲染路径

Unity渲染路径

(四) 可用内置光照变量(名称-类型:描述):

  • _LightColor0-float4:该pass处理的逐像素光源的颜色
  • _WorldSpaceLightPos0-float4:_WorldSpaceLightPos0.xyz是该Pass处理的逐像素光源的位置,若该光源是平行光,则_WorldSpaceLightPos0.w是0,其他光源类型的w值为1。
  • _LightMatrix0-float4:从世界空间到光源空间的变换矩阵,可以用于采样cookie和光强衰减(attenuation)纹理
  • unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0-float4:仅用于Base Pass,前4个非重要的点光源在世界空间中的位置
  • unity_4LightAtten0-float4:仅用于Bass Pass,存储了前4个非重要的点光源的衰减因子
  • unity_LightColor-half4[4]:仅用于Bass Pass,存储了前4个非重要的点光源的颜色

(五)内置光照函数(函数名:描述)

  • float3 WorldSpaceLightDir(float4 v):仅用于前向渲染中,输入一个模型空间中的顶点位置,返回世界空间中从该点到光源的光照方向。内部实现使用了UnityWorldSpaceLightDir函数,没有被归一化
  • float3 UnityWorldSpaceLightDir(float4 v):仅用于前向渲染中,输入一个世界中的顶点位置,返回世界空间中从该点到光源的光照方向,没有被归一化
  • float3 ObjSpaceLightDir(float4 v):输入一个模型空间中的顶点位置,返回世界空间中从该点到光源的光照方向。没有被归一化
  • float3 Shade4PointLights(…):计算四个点光源的光照,它的参数是已经打包进矢量的光照数据,如unity_4LightPosX0,unity_4LightPosY0, unity_4LightPosZ0,unity_LightColor,unity_4LightAtten0等,前向渲染通常使用这个函数计算逐顶点光照