Unity Shader入门精要笔记(八):Unity 的基础光照——概念与理论

  本系列文章由Aimar_Johnny编写,欢迎转载,转载请标明出处,谢谢。

http://blog.csdn.net/lzhq1982/article/details/74529190


这一篇,我们重点讲光照的概念,理论和公式部分。

1、我们是如何看到这个世界的

当我们看到这个物体是红色的,实际上是因为它反射了更多的红光波长,而吸收了其他波长。如果是黑色的,实际上是吸收了绝大多数波长。

通常,我们要模拟真实的光照环境来生成一张图像,需要考虑3种物理现象:

a、光线从光源中被发射出来。

b、光线和场景中的一些物体相交,一些光线被物体吸收了,另一些被散射到其他方向。

c、摄像机吸收了一些光,产生了一张图像。

下面我们对每个部分详细解释。

1)光源

在实时渲染中,我们通常把光源当成一个没有体积的点,用 l 表示它的方向。我们用辐照度(irradiance)来量化光。对于平行光来说,它的辐照度可通过计算在垂直于 l 的单位面积上单位时间内穿过的能量来得到。在计算光照模型时,我们需要知道一个物体表面的辐照度,当物体表面和 l 不垂直时,我们用光线方向 l 和表面法线 n 之间的夹角的余弦值来得到。注意,这里默认方向矢量模为1。下图是使用余弦计算的原因。


辐照度和照射到物体表面光线之间的距离d/cosθ成反比,和cosθ成正比,那和θ成反比,所以θ越小,辐照度越大。因为 l 和 n 的模是1,所以cosθ可以用 l 和 n 的点积求得,这就是点积计算辐照度的由来。

2)吸收和散射

光线与物体相交会发生两种结果:散射和吸收。散射只改变光线方向,不改变密度和颜色。吸收只改变密度和颜色,不改变方向。光线在物体表面散射后,一种将会散射到物体内部,被称为折射(refraction)透射(transmission);另一种会散射到外部,被称为反射(reflection)。对于不透明物体,折射进入物体内部的光线还会继续与内部的颗粒进行相交,其中一些光线最后会重新发射出物体表面,另一些则被物体吸收。那些从物体表面重新发射出的光线将具有和入射光线不同的方向分布和颜色。如下图:


在光照模型中,我们用不同的计算来区分这两种不同的散射:高光反射(specular)表示物体表面是如何反射的,漫反射(diffuse)则表示有多少光线被折射、吸收和散射出表面。根据入射光线的数量和方向,我们可以计算出反射光线的数量和方向,这用出射度(exitance)来描述。本篇中,我们假设漫反射部分是没有方向性的,高光反射也只在一个特定方向上。

3)着色

着色是指根据材质属性(如漫反射属性等),光源信息(如光源方向,福照度等),使用一个等式去计算沿某个观察方向的出射度的过程。我们把这个等式称为光照模型(Lighting Model)。不同的光照模型有不同的目的。比如有用于描述粗糙物体表面的,有用于描述金属表面的等。

4)BRDF光照模型

这是一个高大上的光照模型,这里只是在概念上做个介绍,BRDF(Bidirectional Reflectance Distribution Function,中文名叫双向反射分布函数),当给定模型表面一个点时,BRDF包含了对该点外观的完整描述,用基于物理的模型表现了近似真实的表面和光照交互的完整过程。在图形学中,BRDF大多使用一个公式来表示,并提供了一系列参数来调整材质属性。很强大,当然也很复杂,在书中放到最后一章详细介绍的。我们这里还是从基础看起,用简单的经验模型,达到视觉上能接受的效果。

2、标准光照模型

应用最普遍的光照模型,它的基本方法是,把进入到摄像机的光线分成4部分,每部分使用一种方法计算它的贡献度:

a、自发光(emissive):这个部分用于描述给定一个方向时,一个表面会向该方向发射多少辐射量。注意,如果没有使用全局光照技术,这些自发光表面不会真的照亮周围物体,只是本身看起来更亮了而已。

b、高光反射(specular):当光线照射到模型表面时,该表面会在完全镜面反射方向散射多少辐射量。

c、漫反射(diffuse):当光线照射到表面时,该表面会向每个方向散射多少辐射量。

d、环境光(ambient):其他所有间接光照。

1)环境光

除了直接光照,物体也可以被间接光照照亮,间接光照是光线经过多个物体之间反射,最后进入摄像机。在标准光照模型中,我们用环境光近似模拟间接光照。环境光计算简单,通常是一个全局变量,场景中所有物体都使用这个环境光。下面等式是环境光的计算:


2)自发光

光线直接由光源发射进入摄像机。计算很简单,直接使用该材质的自发光颜色:


3)漫反射

这部分是我们研究的重点,漫反射中,视角的位置是不重要的,因为反射方向是随机的,所以可以认为在任何方向上反射分布都是一样的。但入射光线的角度很重要。漫反射符合兰伯特定律(Lambert's law):反射光线的强度与表面法线和光源方向之间的夹角的余弦成正比。公式如下:


n是法线,I是指向光源的单位矢量,c(light)是光源颜色,m(diffuse)是材质的漫反射颜色。注意,我们需要防止法线和光源方向点乘的结果是负值,所以用了max函数。

4)高光反射

这里的高光反射是一种经验模型,它并不完全符合真实世界的高光反射现象。它可用于计算完全的镜面反射。计算高光反射需要知道法线、视角方向、光源方向、反射方向等。下图给出了这些方向矢量:


当然我们知道前三个即可,反射方向可以算出来:


这样,我们可以用Phong模型计算高光反射:


其中,m(gloss)是材质的光泽度(gloss)。用于控制高光区的两点有多大,值越大,亮点越小。m(specular)是材质的高光反射颜色,c(light)是光源的颜色。同样,也要防止v和r的点乘是负值。

和上面的Phong模型相比,Blinn提出了一个简单的修改方法来得到类似的结果。基本思想是避免计算反射方向r,为此Blinn模型引入一个新矢量h,它可以通过v和I的取平均后再归一化得到。即:


然后,用n和h之间的夹角来计算,而不是v和r之间的夹角。如图:


Blinn模型公式如下:


这两种模型都是经验模型,所以也不能说哪个更优,在一些情况下,Blinn更符合实验结果。

5)逐像素还是逐顶点

我们可以在顶点着色器中计算这些公式,叫逐顶点光照,也可以在片元着色器中计算,叫逐片元光照

逐片元光照中,我们以每个像素为基础,得到它的法线(可以是顶点法线插值得到的,也可以是法线纹理采样得到的),然后进行光照计算。这种在面片之间对顶点法线进行插值的技术被称为Phong着色(Phong shading),也被称为Phong插值法或法线插值着色技术。

逐顶点光照也被称为高洛德着色(Gouraud shading),逐顶点光照中,我们在每个顶点上计算光照,然后会在渲染图元时进行线性插值,最后输出成像素颜色。由于顶点数目往往远小于像素数目,因此逐顶点光照的计算量往往小于逐片元光照。但逐顶点光照是线性插值出来的,当光照模型中有非线性计算(例如计算高光反射)时,逐顶点光照会出问题。而且对顶点颜色的差值也会使图元内部的颜色总是暗于顶点处的颜色,会有可能产生明显的棱角现象。

好了,有关光照的概念和公式计算就介绍到这,但这只是简单的光照,不涉及点光源和聚光灯效果,没有衰减,也没有阴影,以后我们再介绍,这里再多说一点,就是移动平台在光照处理上的各种限制,我们要尽量避免实时光影,实用中有各种技术,比如烘焙,光照贴图,或者各种用纹理效果实现光照的效果,如果非要用,要用尽量简单的光照模型,逐顶点光照等。下一篇我们上代码,学习简单的漫反射效果。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值