第09章 反射模型剖析

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第九章反射模型

本章定义了一组类来描述光源是如何在表面上散射的。回忆一下,在第5.4节中我们介绍了双向反射分布函数(BRDF),来描述光在某个表面上的反射;又介绍了BTDF来描述在表面上的透射,而BSDF把这两种效果综合起来。描述真实表面上的散射的最好方法常常是多个BRDF和BTDF的综合;在第10章里,我们将介绍一个BSDF对象,将多个BRDF和BTDF组合在一起来表示光在表面上的总体上的散射效果。本章不考虑在表面上反射性质和透射性质发生变化的情况,在第11章中,描述纹理的类会处理这个问题。

表面反射模型有几个来源:

1. 实验数据:许多真实世界中的表面的反射分布性质是在实验室里测量出来的。这些数据可以直接放在表格里使用,或者用来计算一组基函数的系数。

2.现象学模型:建立描述真实世界里表面的性质的方程,并且这些方程可以很有效地模拟出这些性质。像BSDF这类模型就非常好用,因为它们可以用直观的参数来改变模型的行为(例如“粗糙度”)。计算机图形学中的许多反射函数都属于这个范畴。

3.仿真:有时我们知道一个表面的组成部分的底层信息。例如,我们可能知道一种颜料是由悬浮在介质中的大小大致相同的彩色颗粒组成的,或者知道一种编织物是有两种类型的线构成,每种线都有已知的反射特性。在这样的情况下,我们可以通过模拟微观几何的散射来得到反射数据。这个模拟过程可以是在渲染中进行的,也可以是一种预处理过程,并由此拟合出一组基函数以备后用。

4. 物理(波动)光学: 有些反射模型是由一种非常精细的光模型推衍出来的,其中光被视为一种波,并通过解麦克斯韦方程来研究光在表面上的散射过程。这些模型通常需要耗时的计算,却并不一定会得到比几何光学模型更精确的结果。

5,几何光学:跟仿真方法相似,如果知道了表面的底层的散射和几何性质,就可以从这些性质中推导出有解析表达式的反射模型。几何光学模型使得光对表面的交互作用更容易处理,因为诸如偏振现象的复杂效应被忽略了。

基本术语

为了比较不同反射模型的视觉效果,我们介绍一些关于表面反射的基本术语。

表面反射可以分为四大类:漫反射(diffuse),光泽镜面反射(glossy specular),理想镜面反射(perfect specular),逆反射(retro-reflective)。大多数表面的反射是这四类反射的混合。漫发射将光线均等地向所有方向上散射。虽然很难见到理想的漫反射表面,但接近漫反射的例子有无光泽的黑板,无光涂料等等。象塑料、高光泽涂料这样的光泽镜面表面向一组特定的方向进行散射--它们可以映照出其它物体的模糊的映像。理想镜面表面只向一个单一的方向散射。镜子和玻璃是理想镜面表面的例子。最后,象天鹅绒或在地球上看到的月亮这样的逆反射表面主要向入射光方向对光线进行散射。(如图:a -漫反射, b -光泽镜面反射, c -理想镜面反射, d -逆反射)。

给定了一个反射类型,反射分布函数可以是各向同性(isotropic)的或者是各向异性(anisotropic)的。大多数物体是各向同性的:如果选定表面上的一个点绕着该点的法向量旋转它,所反射的光的总量不变。相反地,对各向异性材料做这样的旋转,就会反射出不同量的光。各向异性表面的例子有被擦亮的金属、唱机唱片和CD盘片。

几何设置

在pbrt中的反射计算是在一个反射坐标系中进行的,在该坐标系中,被着色的点上的两个切向量和法向量分别跟x,y,z轴对齐,所有BRDF和BTDF函数的传入向量和返回向量都是在这个坐标系下定义的。理解好这个坐标系对后面理解BRDF和BTDF的实现非常重要。

着色坐标系还给出了一个用球面坐标(θ,Φ)来表示方向的标架;角度θ是给定方向跟z轴的夹角,Φ是给定方向在xy平面上的投影跟x轴的夹角。(如图)

给定了在该坐标系中的一个方向,就可以很容易地计算出它与法向量夹角的余弦,等等:

cos θ = (n . ω) = ( (0, 0, 0) . ω) = ωz

下面就是求这个余弦值的工具函数:

=

inline float CosTheta (const Vector &w) { return w.z;}

利用sin2θ + cos2θ = 1, 可得到相应的正弦值:

+=

inline float SinTheta(const Vector &w) {

return sqrtf(max(0.f, 1.f - w.z * w.z));

}

下面是求sin2θ的工具函数:

+=

inline float SinTheta2(const Vector &w) {

return 1.f - CosTheta(w) * CosTheta(w);

}

类似地我们可以用着色坐标系统来简化关于Φ的正弦和余弦计算。在着色点所在的平面上方向ω有坐标(x, y),分别为r cosΦ 和r sinΦ。而半径r即是sin θ,因此:

cos Φ = x / r = x / sin θ

sin Φ = y / r = y / sin θ

+=

inline float CosPhi(const Vector &w) {

return w.x / SinTheta(w);

}

inline float SinPhi(const Vector &w) {

return w.y / SinTheta(w);

}

我们要遵守的一个约定是,入射光ωi和向外的观察方向ωo 在被变换到表面上的局部坐标系以后,都是被正规化的,且方向都朝外。根据约定,表面法向量总是指向物体之外的,这就很容易确定光线是进入还离开透光物体:如果入射光方向ωi跟n在同一个半球,则光线是在进入,否则就是在离开。

因此,需要记住的这一点:表面法向量可能跟ωi或者ωo(或者两者都有)不在物体的同一侧。跟许多其它渲染器不同的是,pbrt并不为了保持ωo和法向量在表面同一侧而翻转法向量。所以,在实现BRDF和BTDF时就不能做这样的假定。

还有,应该注意用于着色的局部坐标系可能并不等同于Shape::Intersect()所返回的坐标系,它们在求交过程和着色过程之间可以做些改动以达到象凸凹纹理映射(bump mapping)这类的效果。

相关文档
最新文档