- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第03章 形体
第三章形体本章介绍pbrt所用的诸如球、三角形等几何体素的抽象定义。在光线追踪器中,对一个清晰明了的系统设计而言,几何形体的精细的抽象定义是必不可少的关键部分,也是对面向对象方法的理想应用。所以几何体素都实现一个公共接口,渲染器的其它部分只需使用这个接口,而不必关心相关形体的细节。这就把pbrt的几何子系统和着色子系统隔离开来。没有这个隔离,加入一个新形体就很困难,也容易出错。pbrt把几何体素的细节隐藏在两重抽象之后。Shape类提供了对几何体素的基本几何性质的存取方法,比如求表面面积、包围盒,还有光线求交例程。 Primitive类提供了额外的非几何的信息,比如材质。渲染器的其它部分只跟Primitive抽象接口打交道。本章主要介绍Shape 类,Primitive接口会在第四章中介绍。3.1 基本形体接口Shape类使用了引用计数方法 -- pbrt对每个形体都保持对其引用的计数,当计数为零时,该形体就被自动删除。虽然这个方法并非绝对有效,但这也是垃圾回收的一种方式,省去了对错误地释放形体的内存的担心。ReferenceCounted类实现了所有底层的相关机制(见A.2.2节)。Shape Declarations =? ? class COREDLL Shape : public ReferenceCounted {? ? public:? ?? ???Shape Interface? ?? ???Shape Public Data? ? };所有形体都是在物体坐标系中定义的。例如,所有球面的球心是物体坐标系的原点。为了把一个球面放置在场景中,必须提供从物体空间到世界空间的变换。 Shape类存放变换的矩阵和它的逆阵。另外,Shape还有一个布尔参量:reverseOrientation, 用来决定是否反转表面法向量的方向。这一点很重要,因为法向量的方向常被用来决定形体的哪一侧是“外面”。例如,对于发光的形体而言,只有在法向量方向所指的一侧才发光。该参量可以由pbrt输入文件的ReverseOrintation语句说明。Shape还存放对Transform::SwapsHandedness()调用的结果。每次找到光线交点时,该值要被用来构造DifferentialGeometry对象。所以,Shape构造器求出该值并存起来。Shape Method Definitions =? ? Shape::Shape(const Transform o2w, bool ro)? ?? ???: ObjectToWorld(o2w), WorldToObject(o2w.GetInverse()),? ?? ???reverseOrientation(ro),? ?? ???transformSwapsHandedness(o2w.SwapsHandedness()) {? ? }Shape Public Data =? ? const Transform ObjectToWorld, WorldToObject;? ? const bool reverseOrientation, transformSwapsHandedness;3.1.1 求包围盒每个形体都要实现求包围盒的函数,有两种函数:ObjectBound()返回形体在物体空间的包围盒,WorldBound()返回在世界空间的包围盒。第一个函数的实现由每个子类给出,而第二个函数有一个缺省的实现,即把物体空间中的包围盒变换到世界空间中并返回变换后的结果。如果形体很容易在世界空间中求得更紧密的包围盒(如三角形),就应该重写(override)该函数。Shape Interface =? ? virtual BBox ObjectBound() const = 0;Shape Interface +=? ? virtual BBox WorldBound() const {? ?? ???return ObjectToWorld(ObjectBound());? ? }3.1.2 加细(Refinement)并不是每个形体都能确定是否可以跟光线求交,例如,一个复杂的曲面先要细分成三角形才可以求交。还有可能一个形体只是用来代表存储在硬盘上的大量的形体的聚合。这时我们仅仅在内存中保留相应的几何信息文件和包围盒,只有当光线跟包围盒相交时,才把文件读到内存中。Shape::CanIntersect()的缺省实现只返回真值,表示该形体“能”计算光线求交,所以那些不能求交的形体要重写该函数。Shape Interface +=? ? virtual bool CanIntersect() const { return true; }如果形体不可以直接求光线交点,那么它必须提供Shape:
文档评论(0)